import java.awt.Color;
import java.awt.event.*;
import java.io.*;

public class APSUEngine implements KeyListener {
	
	String visa = "validation"; //VALIDATION PASSWORD - default 'visa'
	APServer gui;
	
	//Whitelist, imported from Antonymv1.5+
	String[] whiteList = { "Username", "Pat", "zacnowicki", "amamendoza", "timhall", "frabuot", "danmuise", "wenshao", "stegaiero", "antkhoury", "petcomeau", "susfritchy", "jamtellier", "davdelory", "rolcodair" };
	//badLang, imported from Antonym1.5+ (thanks stephen, rollie, others!)
	String[] badLang = {"jerkoff",  "idiot", "fuck","bitch","whore","cunt","cock","dick","penis","homo","fag","ass","shit","tits","jizz","nigg","faggot","blow job","cock sucker","vagina","hand job","dike","lesbian","cum","office tech","slut", "pussy", "tits", "titties", "spick", "sit on it and rotate" };
	
	String[] helpList = { "whitehats - prints all valid usernames", "langlist - prints language filter contents", "exit - exits the application", "bulletin [clear] OR b [clear] - Adds to bb.html. Resets the file if clear is not omitted.", "post [author] [thread] [content] - Creates a new post or appends an existing one." };
		
	public APSUEngine(APServer in) { //gui instance
		
		gui=in;
		
	}
	
	public void s(String out) { //console display shortcut
		
		gui.toConsole("engine :: " + out);
		
	}
	
	public void think(String command, String validation) { //command line interpreter
		
		gui.line.setText("");
		
		String out;
		
		if(validation.equals(visa)) {
			
			if(command.isEmpty()) {
				
				gui.popup("You must enter a command.", "Syntax Error");
				
				
			} else {
			
				gui.validate.setBackground(Color.green);
				out = "admin> " + command;
				gui.toConsole(out);
				
				
				if(command.equals("?") | command.equals("help")) { listHelp(); }
				
				if(command.equals("start")) { gui.initServer(); }
				
				if(command.equals("stop")) { gui.stopServer(); }
				
				if(command.equals("whitehats")) { listWhite(); }
				
				if(command.equals("langlist")) { listLang(); }
				
				if(command.startsWith("bulletin ")) {
					
					if(command.endsWith("clear")) {
						
						bulletin(null,true);
						
					} else {
						
						String send = command.substring(9,command.length());
						bulletin(send,false);
						
					}
					
				}
				
				if(command.startsWith("b ")) {
					
					if(command.endsWith("clear")) {
						
						bulletin(null,true);
						
					} else {
						
						String send = "<br>" + command.substring(2,command.length());
						bulletin(send,false);
						
					}
					
				}
				if(command.startsWith("post ")) {
					
					String[] params = parse(command);
					int startIndex=(params[1].length() + 1) + (params[2].length() + 1);
					post(params[1],params[2],command.substring(startIndex+4, command.length()));
				}
				
				if(command.equals("exit")) { System.exit(0); }
		
			}
			
		} else {
			
			s("-* Incorrect Validation Code *-");
			gui.validate.setBackground(Color.RED);
			gui.popup("You must enter the correct validation.","Invalid Validation");
			
		}
		novel();
	}
	
	@SuppressWarnings("deprecation")
	@Override
	public void keyPressed(KeyEvent arg0) { //command line submission (enter key)
		
		int key = arg0.getKeyCode();
		
		if(key == KeyEvent.VK_ENTER) {
			
			think(gui.line.getText(), gui.validate.getText());
			
		}
		
	}

	@Override
	public void keyReleased(KeyEvent arg0) { //nothing: override only
		
		
	}

	@Override
	public void keyTyped(KeyEvent arg0) { //nothing: override only
		
		
	}
	
	public String[] parse(String input) { //TODO nearly-deprecated parsing function 
		
		String delims = "[ ]+"; 
		String[] parsed = input.split(delims);

		return parsed;
	}
	
	public void listWhite() { //dump whitelist contents
		
		s("~<! printing white list !>~");
		for(int i=1; i < whiteList.length; i++) {
			
			s("$ " + whiteList[i]);
			
		}
		
		s("~<! done !>~");
	}
	
	public void listLang() { //dump badlang contents
		
		s("~<! printing badLang !>~");
		for(int i=1; i < badLang.length; i++) {
			
			s("# " + badLang[i]);
			
		}
		
		s("~<! done !>~");
		
	}
	
	public void listHelp() { //dump help contents
		
		s("~<! display help index !>~");
		for(int i=0; i < helpList.length; i++) {
			
			s("? " + helpList[i]);
			
		}
		
		s("~<! done !>~");
		
	}
	
	public void novel() { //server activity log
		
		File log = new File("logs/serverlog.log");
		FileOutputStream out = null;
		try {
			
			out = new FileOutputStream(log);
			
		} catch (FileNotFoundException e) {
			
			try {
				
				s("new log file created: servlog.log");
				log.createNewFile();
				
				
			} catch (IOException e1) {
				
				s("error: could not make log file: " + e.getMessage());				
			}
			
		}
		try {
			out.write(gui.console.getText().getBytes());
		} catch (IOException e) {
			
			s("log file write error: " + e.getMessage());
		}
		
	}

	public void bulletin(String add, boolean clear) { //admin bulliten board control (to be expanded to post method)
		
		File bb = new File("bb.html");
		FileInputStream in=null;
		try {
			in = new FileInputStream(bb);
		} catch (FileNotFoundException e) {
			
			s("error: " + e.getMessage());
		}
		
		byte[] prev = new byte[((int) bb.length())-14];
		try {
			in.read(prev);
		} catch (IOException e) {
			
			s("error: " + e.getMessage());
		}
		
		try {
			in.close();
		} catch (IOException e) {
			
			s("error: " + e.getMessage());
		}
		
		FileOutputStream out = null;
		
		try {
			out= new FileOutputStream(bb);
		} catch (FileNotFoundException e) {
			
			s("error: " + e.getMessage());
			
		}
		if(clear) {
			
			String blank="<HTML><TITLE>APSUV - Admin Bulletin Page</TITLE><HEAD></HEAD><BODY BGCOLOR=BLACK><FONT FACE=complex COLOR=purple><center><H1>admin bulletin</h1></center><FONT COLOR=yellow></BODY></HTML>";
			s("bulletin :: reset");
			try {
				out.write(blank.getBytes());
			} catch (IOException e) {
				
				s("error: " + e.getMessage());
			}
			
		} else {
		
			try {
				out.write(prev);
			} catch (IOException e) {
			
				s("error: " + e.getMessage());
			}
			try {
				add += "</BODY></HTML>";				
				s("bulletin :: updated");
				out.write(add.getBytes());				
			} catch (IOException e) {
			
				s("error: " + e.getMessage());
			}
			
		}
		
	}
	
	public void post(String author, String thread, String content) {
		
		File target = new File("threads\\" + thread + ".html");
		FileInputStream in = null;
		FileOutputStream out = null;
		
		//TEMPLATE FOR NEW THREADS | REFERANCE FOR APPENDING EXISTING
		String template = "<HTML><HEAD><hr><TITLE>" + author + ".:." + thread + "</TITLE></HEAD>\r<BODY BGCOLOR=BLACK>\r<FONT COLOR=WHITE>\r<h1>" + author + ": " + thread + "</h1>\r" + content + "\r<hr>\r</BODY>\r</HTML>";
		
			try {
				//APPENDING----------
				in = new FileInputStream(target);
				byte[] prev = new byte[(int) target.length()-16]; //Read up to the last bit
				
				try {
					in.read(prev);
				} catch (IOException e) {
						
					s("error while posting: " + e.getMessage());
					
				}
				
				try {
					in.close();
				} catch (IOException e) {
					
					s("error while closing: " + e.getMessage());
					
				}
				//------------
				out = new FileOutputStream(target);
				String aformat = "<hr><h3>" + author + "</h3><br>";
				String close = "<br></BODY></HTML>";
				//ADD OLD STUFF + NEW STUFF
				try {
					out.write(prev);
				} catch (IOException e) {
					s("error while writing: " + e.getMessage());					
				}
				try {
					out.write(aformat.getBytes());
				} catch (IOException e) {
					s("error while writing: " + e.getMessage());
				}
				try {
					out.write(content.getBytes());
				} catch (IOException e) {
					s("error while writing: " + e.getMessage());
				}
				s("post appended");
				try {
					out.write(close.getBytes());
				} catch (IOException e) {
					s("error while writing: " + e.getMessage());
				}
				
				try {
					out.close();
				} catch (IOException e) {
					s("error while closing: " + e.getMessage());
				}
				
				//DONE APPENDING
			
			
			} catch (FileNotFoundException e1) {
				//CREATING----------
				
				try {
					target.createNewFile();
				} catch (IOException e2) {
					s("error while creating file: " + e2.getMessage());
				}
				try {
					out = new FileOutputStream(target);
				} catch (FileNotFoundException e3) {
					s("error: " + e3.getMessage());
				}
				
				s("post created");
				
				try {
					out.write(template.getBytes());
				} catch (IOException e) {
					s("error while writing: " + e.getMessage());
				}
				
				s("write successful");
				
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					s("error while closing: " + e.getMessage());
				}
			
			
			}
		
	}
}